package cn.fff.system.service.impl;

import cn.fff.model.system.SysMenu;
import cn.fff.model.system.SysRole;
import cn.fff.model.system.SysRoleMenu;
import cn.fff.model.system.SysUserRole;
import cn.fff.model.vo.AssignMenuVo;
import cn.fff.model.vo.AssignRoleVo;
import cn.fff.model.vo.MenuTreeCheckVo;
import cn.fff.model.vo.SysRoleQueryVo;
import cn.fff.system.mapper.SysRoleMapper;
import cn.fff.system.mapper.SysRoleMenuMapper;
import cn.fff.system.mapper.SysUserRoleMapper;
import cn.fff.system.service.SysMenuService;
import cn.fff.system.service.SysRoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public IPage<SysRole> selectPage(Page<SysRole> pageParam, SysRoleQueryVo sysRoleQueryVo) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<SysRole>();
        if (StringUtils.isNotBlank(sysRoleQueryVo.getRoleName())) {
            wrapper.like(SysRole::getRoleName, sysRoleQueryVo.getRoleName());

        }
        wrapper.orderByDesc(SysRole::getId);
        IPage<SysRole> pageResult = this.page(pageParam, wrapper);
//        IPage<SysRole> pageResult = baseMapper.selectPage(pageParam, sysRoleQueryVo);
        return pageResult;
    }

    @Override
    public Map<String, Object> getRolesByUserId(String userId) {
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, userId);
        List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(wrapper);
        List<SysRole> alllRoles = this.list();
        List<String> userRoleIds = sysUserRoles.stream()
                .map(SysUserRole::getRoleId).collect(Collectors.toList());
        Map<String, Object> result = new HashMap<>();
        result.put("allRoles", alllRoles);
        result.put("userRoleIds", userRoleIds);
        return result;
    }

    @Override
    public void doAssign(AssignRoleVo vo) {
        // 根据用户分配角色
        // 1. 删除原来的角色
        LambdaQueryWrapper<SysUserRole> wrapper1 = new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, vo.getUserId())
                .notIn(SysUserRole::getRoleId, vo.getRoleIdList());
        sysUserRoleMapper.delete(wrapper1);
        // 2. 查询现在已有角色
        LambdaQueryWrapper<SysUserRole> wrapper2 = new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, vo.getUserId());
        List<SysUserRole> assignedRoles = sysUserRoleMapper.selectList(wrapper2);
        List<String> assignedRoleIds = assignedRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        // 3. 添加新角色
        // 3.1 获取需要添加的新角色
        List<String> toAddRoleIds = new ArrayList<>();
        for (String roleId : vo.getRoleIdList()) {
            if (!assignedRoleIds.contains(roleId)) {
                toAddRoleIds.add(roleId);
            }
        }
        for (String toAddRoleId : toAddRoleIds) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(vo.getUserId());
            sysUserRole.setRoleId(toAddRoleId);
            sysUserRoleMapper.insert(sysUserRole);
        }
    }

//    @Override
//    public List<SysMenu> findMenuByRoleId(Long roleId) {
//        List<SysMenu> nodes = sysMenuService.findNodes();
//        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
//        wrapper.select(SysRoleMenu::getMenuId, SysRoleMenu::getId).eq(SysRoleMenu::getRoleId, roleId);
//        List<SysRoleMenu> sysRoleMenus = sysRoleMenuMapper.selectList(wrapper);
//        Set<String> selectedMenuIds = sysRoleMenus.stream().map(SysRoleMenu::getMenuId)
//                .collect(Collectors.toSet());
//        nodes.forEach(e -> setIsSelect(e, selectedMenuIds));
//        return nodes;
//    }
//
//    private void setIsSelect(SysMenu sysMenu, Set<String> selectedMenuIds) {
//        if (null == sysMenu) return;
//        if (selectedMenuIds.contains(sysMenu.getId().toString())) {
//            sysMenu.setSelect(true);
//        }
//        if (sysMenu.getChildren() != null) {
//            sysMenu.getChildren().forEach(e -> setIsSelect(e, selectedMenuIds));
//        }
//    }

    @Override
    public MenuTreeCheckVo findMenuByRoleId(Long roleId) {
        List<SysMenu> nodes = sysMenuService.findNodes();
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SysRoleMenu::getMenuId, SysRoleMenu::getId).eq(SysRoleMenu::getRoleId, roleId);
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuMapper.selectList(wrapper);
        List<String> checkedMenuIds = sysRoleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        MenuTreeCheckVo menuTreeCheckVo = new MenuTreeCheckVo(nodes, checkedMenuIds);
        return menuTreeCheckVo;
    }

    @Override
    public void authMenu(AssignMenuVo vo) {
        // 1. 删除未授权的菜单
        LambdaQueryWrapper<SysRoleMenu> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(SysRoleMenu::getRoleId, vo.getRoleId())
                        .notIn(SysRoleMenu::getMenuId, vo.getMenuIdList());
        sysRoleMenuMapper.delete(deleteWrapper);
        // 2. 查询已授权的菜单
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, vo.getRoleId());
        Set<String> existMenuIds = sysRoleMenuMapper.selectList(queryWrapper)
                .stream().map(SysRoleMenu::getMenuId).collect(Collectors.toSet());
        // 3. 获取待授权的菜单
        List<String> toAuthMenuIds = vo.getMenuIdList().stream()
                .filter(e -> !existMenuIds.contains(e)).collect(Collectors.toList());
        toAuthMenuIds.forEach(menuId -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(vo.getRoleId());
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenuMapper.insert(sysRoleMenu);
        });
    }


}
